/**
  ETFDAQ Project -- online from ETFAna Online by SUN Yazhou
  \class TAReadShm
  \brief read data from daq shm, and write to TAQueue for further processing
  Supposed to be a tool class
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2023-06-08
  \date 2023-06-08 last modified
  \attention
  changelog
  <table>
  <tr>  <th>Date         <th>Author      <th>Description                    </tr>
  <tr>  <td>2023-06-08   <td>Asia Sun    <td>file created                   </tr>
  </table>

  \copyright Copyright (c) 2021-2024 Anyang Normal U. && IMP-CAS with LGPLv3 LICENSE
*/

#ifndef TAReadShm_h
#define TAReadShm_h

#include <string>
#include <signal.h>
#include "TADaqData.h"

using std::string;

class TAShm;
struct online_shm;

class TAReadShm : public TADaqData{
public:
  TAReadShm();
  /// \param name the posix shm name to read from
  /// \param isCreate whether to create shm if not exists
  TAReadShm(const string &name, DaqType daqType = kPXI, bool isCreate = false);
  virtual ~TAReadShm();

  void CreateShm(const string &name, bool isCreate = false);
  void CleanShm(); // just recover last abnormal exit (mainly do some sem_post's)
  TAShm *GetShm() const{ return fShm; }
  TAShm *shm() const{ return fShm; }
  online_shm *buf() const{ return fBuf; }
  int nstored() const{ return peeksem(fBuf->nstored); }
  int nempty() const{ return peeksem(fBuf->nempty); }
  int mutex() const{ return peeksem(fBuf->mutex); }
  virtual void ShmStatus(); ///< print shm status

  virtual void Initialize() override; // initiate the thread
  virtual void Close() override; ///< close the shm or socket
  /// initialize the shared memory \param reinit whether 1st init or not
  void InitShm(bool reinit = false);

  void read(); ///< read from daq shm
  // write 1 event to daq shm - sim daq to debug online
  void write(const void *src); ///< note that this function does not goes into any thread

  static bool exist(const string &name); ///< to tell if a sem exists
  static int peeksem(sem_t &s); ///< utility function, e.g., for gdb

  // facilities to facilitate immediate reaction to ctrl-C //
  friend void *handle_ctrlc_readShm(void *qq);
  friend void handler_readShm(int sig, siginfo_t *info, void *context);

protected:
  /// thread func, made member to avoid namespace contamination
  static void *avatar(void *rshm);

  TAShm *fShm; ///< pointer to the daq shm
  online_shm *fBuf; ///< pointer to the buffer of fShm
  int fMAX_NUM, fMAX_LEN; ///< fBuf->MAX_NUM, fBuf->MAX_LEN
};

#endif
